import os
import subprocess
from urllib.parse import urlparse
from flask import Blueprint, render_template, request, redirect, url_for, flash, jsonify, session, current_app,jsonify
from .models import db, User, Dorm, Allocation, DormType, Meter, UtilityFee, Admin
from datetime import datetime, timedelta
from sqlalchemy import extract
from .utils import admin_required  # 引入装饰器
from math import ceil

bp = Blueprint('main', __name__)



# 备份 MySQL 数据库的路由
@bp.route('/backup', methods=['GET', 'POST'])
@admin_required
def backup_mysql():
    backup_folder = current_app.config.get('BACKUP_FOLDER', 'backups/')  # 默认备份目录

    if not os.path.exists(backup_folder):
        os.makedirs(backup_folder, exist_ok=True)

    # 获取备份目录下的所有文件，并按时间排序
    backup_files = sorted(
        os.listdir(backup_folder),
        key=lambda f: os.path.getmtime(os.path.join(backup_folder, f)),
        reverse=True
    )
    # 收集文件详细信息
    backup_file_details = []
    for file in backup_files:
        file_path = os.path.join(backup_folder, file)
        file_size = os.path.getsize(file_path) / 1024  # 获取文件大小，单位KB
        file_timestamp = os.path.getmtime(file_path)
        formatted_date = datetime.fromtimestamp(file_timestamp).strftime('%Y-%m-%d %H:%M:%S')

        backup_file_details.append({
            'filename': file,
            'size': round(file_size, 2),  # 保留2位小数
            'timestamp': formatted_date
        })
    # 显示备份文件列表
    if request.method == 'GET':
        return render_template('admin/backup.html', backup_files=backup_file_details)

    if request.method == 'POST':
        try:
            # 获取数据库配置
            db_uri = current_app.config['SQLALCHEMY_DATABASE_URI']
            parsed_uri = urlparse(db_uri)
            db_user = parsed_uri.username
            db_password = parsed_uri.password
            db_host = parsed_uri.hostname
            db_name = parsed_uri.path.lstrip('/')

            # 生成备份文件名
            timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
            backup_filename = f"backup_{timestamp}.sql"
            backup_path = os.path.join(backup_folder, backup_filename)

            # 执行 mysqldump 命令
            dump_command = [
                'mysqldump',
                '-h', db_host,
                '-u', db_user,
                '--password=' + db_password,  # 正确传递密码
                db_name
            ]

            # 执行备份命令
            with open(backup_path, 'w') as backup_file:
                result = subprocess.run(dump_command, check=True, stdout=backup_file, stderr=subprocess.PIPE)

                if result.stderr:
                    print(result.stderr.decode())  # 打印错误输出，便于调试

            flash(f'备份成功！备份文件：{backup_filename}', 'success')

            # 再次加载备份列表，显示备份信息
            backup_files = sorted(
                os.listdir(backup_folder),
                key=lambda f: os.path.getmtime(os.path.join(backup_folder, f)),
                reverse=True
            )
            backup_file_details = []
            for file in backup_files:
                file_path = os.path.join(backup_folder, file)
                file_size = os.path.getsize(file_path) / 1024
                file_timestamp = os.path.getmtime(file_path)
                formatted_date = datetime.fromtimestamp(file_timestamp).strftime('%Y-%m-%d %H:%M:%S')
                backup_file_details.append({
                    'filename': file,
                    'size': round(file_size, 2),
                    'timestamp': formatted_date
                })

            return render_template('admin/backup.html', backup_files=backup_file_details)

        except subprocess.CalledProcessError as e:
            flash(f'备份失败: {e.stderr.decode()}', 'danger')
            return redirect(url_for('main.backup_mysql'))
        except Exception as e:
            flash(f'备份失败: {str(e)}', 'danger')
            return redirect(url_for('main.backup_mysql'))


# 网站首页用户登录：
@bp.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        username = request.form.get('username')
        password = request.form.get('password')

        # 使用 User 模型查询数据库
        user = User.query.filter_by(username=username).first()  # 查询用户名

        if user and user.check_password(password):  # 如果用户存在且密码正确
            # 登录成功，设置会话
            session['id'] = user.id  # 存储用户ID
            session['username'] = user.username  # 存储用户名
            session.permanent = True  # 使session永久有效，使用设置的过期时间
            flash('登录成功!', 'success')
            return redirect(url_for('main.member'))  # 登录成功后跳转到首页
        else:
            flash('用户名或密码错误', 'danger')  # 提示错误信息
            return redirect(url_for('main.index'))  # 重新加载登录页面
    return render_template('user/index.html')

# 登出视图
@bp.route('/member_logout')
def member_logout():
    # 清除会话信息
    session.clear()
    flash('已成功登出', 'success')
    return redirect(url_for('main.index'))  # 返回登录页面


# 前端会员中心：
@bp.route('/member')
def member():
    return render_template('user/member.html')






# 登录页面
@bp.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        name = request.form.get('name')
        password = request.form.get('password')

        # 查询管理员
        admin = Admin.query.filter_by(name=name).first()
        if admin and admin.check_password(password):
            # 登录成功，设置会话
            session['id'] = admin.id  # 存储管理员ID
            session['name'] = admin.name  # 存储管理员姓名
            session.permanent = True  # 使session变得永久有效，使用设置的过期时间
            return jsonify({'success': True, 'msg': '登录成功'})
        else:
            return jsonify({'success': False, 'msg': '用户名或密码错误'})

    return render_template('admin/login.html')


# 登出页面
@bp.route('/logout')
def logout():
    session.pop('id', None)  # 清除会话
    session.pop('name', None)  # 清除会话
    flash('成功退出登录', 'info')
    return redirect(url_for('main.login'))  # 重定向到首页


# 后台首页：
@bp.route('/admin')
@admin_required
def admin():
    return render_template('admin/main.html')


# 后台管理员管理页面
@bp.route('/admin_user', methods=['GET', 'POST'])
@admin_required
def admin_user_management():
    admins = Admin.query.all()  # 获取所有管理员
    return render_template('admin/admin_user_management.html', admins=admins)


# 添加管理员
@bp.route('/admin_user/add', methods=['GET', 'POST'])
@admin_required
def admin_user_add():
    if request.method == 'POST':
        name = request.form.get('name')
        admin_name = request.form.get('admin_name')
        password = request.form.get('password')

        # 检查name是否已存在数据库
        if Admin.query.filter_by(name=name).first():
            flash('用户名已存在', 'danger')  # 使用flash()显示错误信息
            return redirect(url_for('main.admin_user_add'))  # 重定向回添加页面

        if name and admin_name and password:
            # 创建一个新的管理员并加密密码
            admin = Admin(name=name, admin_name=admin_name)
            admin.set_password(password)  # 假设有set_password方法来加密密码
            db.session.add(admin)
            db.session.commit()
            flash('管理员添加成功！', 'success')
            return redirect(url_for('main.admin_user_management'))  # 添加成功后跳转到管理员列表页
        flash('请填写所有字段！', 'danger')

    return render_template('admin/admin_user_add.html')





#编辑管理员
@bp.route('/admin_user_edit/<int:id>', methods=['GET', 'POST'])
@admin_required
def admin_user_edit(id):
    admin = Admin.query.get_or_404(id)  # 查找管理员
    if request.method == 'POST':
        admin.name = request.form.get('name')
        admin.admin_name = request.form.get('admin_name')
        password = request.form.get('password')

        # 如果密码不为空，并且用户修改了密码，则进行哈希处理
        if password and password != admin.password:
            admin.set_password(password)

        db.session.commit()
        flash('管理员信息更新成功！', 'success')
        return redirect(url_for('main.admin_user_management'))

    return render_template('admin/admin_user_edit.html', admin=admin)


# 删除管理员
@bp.route('/admin_user_delete/<int:admin_id>', methods=['POST'])
@admin_required
def admin_user_del(admin_id):
    admin = Admin.query.get_or_404(admin_id)  # 查找管理员
    db.session.delete(admin)
    db.session.commit()
    flash('管理员删除成功！', 'success')
    return redirect(url_for('main.admin_user_management'))


# 显示所有用户
@bp.route('/user')
@admin_required
def user():
    # 每页显示的用户数，默认为 10
    per_page = request.args.get('per_page', 10, type=int)

    # 获取当前页数，默认为第一页
    page = request.args.get('page', 1, type=int)

    # 获取分页后的用户列表
    users = User.query.paginate(page=page, per_page=per_page, error_out=False)  # False 表示不自动获取总页数

    dorms = Dorm.query.all()  # 获取所有宿舍，供选择

    # 获取每个用户当前分配的宿舍
    user_dorms = {}
    for user in users.items:  # `users.items` 是当前页的用户列表
        allocation = Allocation.query.filter_by(user_id=user.id).first()
        if allocation:
            dorm = Dorm.query.get(allocation.dorm_id)
            user_dorms[user.id] = dorm.name if dorm else None
        else:
            user_dorms[user.id] = None  # 如果没有分配宿舍，设置为 None

    # 计算总页数
    total_pages = ceil(users.total / per_page)

    return render_template('admin/user_list.html', users=users, dorms=dorms, user_dorms=user_dorms,
                           total_pages=total_pages, per_page=per_page)


# 添加用户页面
@bp.route('/add_user', methods=['GET', 'POST'])
@admin_required
def add_user():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        employee_id = request.form['employee_id']
        gender = request.form['gender']
        phone = request.form['phone']

        # 表单验证
        if not username or not password:
            return '请输入密码', 400

        # 检查工号是否已存在
        if User.query.filter_by(employee_id=employee_id).first():
            flash('工号已存在', 'danger')  # 使用flash()显示错误信息
            return redirect(url_for('main.user'))  # 重定向回添加页面

        # 创建新用户
        new_user = User(username=username, employee_id=employee_id, gender=gender, phone=phone)
        new_user.set_password(password)  # 设置哈希后的密码
        db.session.add(new_user)
        db.session.commit()

        # 重定向到首页或用户列表
        return redirect(url_for('main.user'))

    return render_template('admin/user_add.html')


# 编辑用户页面
@bp.route('/edit_user/<int:id>', methods=['GET', 'POST'])
@admin_required
def edit_user(id):
    user = User.query.get_or_404(id)

    if request.method == 'POST':
        user.username = request.form['username']
        password = request.form['password']
        user.employee_id = request.form['employee_id']
        user.gender = request.form['gender']
        user.phone = request.form['phone']

        # 如果密码不为空，并且用户修改了密码，则进行哈希处理
        if password and password != user.password:
            user.set_password(password)

        db.session.commit()
        return redirect(url_for('main.user'))

    return render_template('admin/user_edit.html', user=user)



# 删除用户
@bp.route('/delete_user/<int:id>', methods=['POST'])
@admin_required
def delete_user(id):
    user = User.query.get_or_404(id)
    db.session.delete(user)
    db.session.commit()
    return redirect(url_for('main.user'))


# 显示所有宿舍
@bp.route('/Dorm')
@admin_required
def dorm_list():
    dorms = Dorm.query.all()
    dorm_types = DormType.query.all()  # 查询所有楼栋

    # 为每个宿舍计算可住人数和剩余人数
    for dorm in dorms:
        dorm.remaining_beds = dorm.bed_count - dorm.occupied

    return render_template('admin/dorm_list.html', dorms=dorms, dorm_types=dorm_types)


# 添加宿舍
@bp.route('/add_dorm', methods=['GET', 'POST'])
@admin_required
def add_dorm():
    dorm_types = DormType.query.all()
    if request.method == 'POST':
        dorm_typeid = request.form['dorm_typeid']
        name = request.form['name']
        typename = request.form['typename']
        bed_count = request.form['bed_count']

        new_dorm = Dorm(dorm_typeid=dorm_typeid, name=name, typename=typename, bed_count=bed_count)
        db.session.add(new_dorm)
        db.session.commit()

        return redirect(url_for('main.dorm_list'))

    return render_template('admin/dorm_add.html', dorm_types=dorm_types)


# 编辑宿舍
@bp.route('/edit_dorm/<int:id>', methods=['GET', 'POST'])
@admin_required
def edit_dorm(id):
    dorm_types = DormType.query.all()
    dorm = Dorm.query.get_or_404(id)  # 获取指定 ID 的宿舍

    if request.method == 'POST':
        dorm.dorm_typeid = request.form['dorm_typeid']
        dorm.name = request.form['name']
        dorm.typename = request.form['typename']
        dorm.bed_count = request.form['bed_count']

        db.session.commit()
        return redirect(url_for('main.dorm_list'))

    return render_template('admin/dorm_edit.html', dorm=dorm, dorm_types=dorm_types)


# 删除宿舍
@bp.route('/delete_dorm/<int:id>', methods=['POST'])
@admin_required
def delete_dorm(id):
    dorm = Dorm.query.get_or_404(id)
    db.session.delete(dorm)
    db.session.commit()
    return redirect(url_for('main.dorm_list'))


# 关联获取楼栋
@bp.route('/dorm/types', methods=['GET'])
@admin_required
def get_dorm_types():
    dorm_types = DormType.query.all()
    dorm_types_data = [{"id": dorm_type.id, "name": dorm_type.name} for dorm_type in dorm_types]
    return jsonify(dorm_types_data)


# 查看楼栋
@bp.route('/dorm_type')
@admin_required
def dorm_type():
    dorm_types = DormType.query.all()  # 查询所有楼栋
    dorms = Dorm.query.all()
    return render_template('admin/dorm_type.html', dorm_types=dorm_types, dorms=dorms)


# 添加楼栋
@bp.route('/dorm_type/add', methods=['GET', 'POST'])
@admin_required
def add_dorm_type():
    if request.method == 'POST':
        name = request.form['name']
        new_dorm_type = DormType(name=name)
        db.session.add(new_dorm_type)
        db.session.commit()
        return redirect(url_for('main.dorm_type'))
    return render_template('admin/dorm_type_add.html')


# 编辑楼栋
@bp.route('/edit_dorm_type/<int:id>', methods=['GET', 'POST'])
@admin_required
def edit_dorm_type(id):
    dorm_type = DormType.query.get_or_404(id)
    if request.method == 'POST':
        dorm_type.name = request.form['name']
        db.session.commit()
        return redirect(url_for('main.dorm_type'))  # 编辑后重定向到楼栋名列表页
    return render_template('admin/dorm_type_edit.html', dorm_type=dorm_type)


# 删除楼栋
@bp.route('/delete_dorm_type/<int:id>', methods=['GET'])
@admin_required
def delete_dorm_type(id):
    # 假设你已经有一个 DormType 模型
    dorm_type = DormType.query.get_or_404(id)
    db.session.delete(dorm_type)
    db.session.commit()
    return redirect(url_for('main.dorm_type'))  # 删除后重定向回楼栋名列表页


# 查询楼栋下的宿舍
@bp.route('/get_dorms_by_type/<int:dorm_type_id>', methods=['GET'])
@admin_required
def get_dorms_by_type(dorm_type_id):
    # 查询宿舍
    dorms = get_dorms_for_type(dorm_type_id)  # 调用 get_dorms_for_type 查询
    return jsonify({'dorms': [{'id': dorm.id, 'name': dorm.name} for dorm in dorms]})


# 定义获取宿舍的函数
def get_dorms_for_type(dorm_type_id):
    return Dorm.query.filter_by(dorm_typeid=dorm_type_id).all()  # 使用 SQLAlchemy 查询宿舍


# 查看宿舍分配
@bp.route('/allocate_list')
@admin_required
def allocate_list():
    dorm_types = DormType.query.all()  # 查询所有楼栋
    allocate_lists = Allocation.query.all()  # 查询所有宿舍分配
    return render_template('admin/allocate_list.html', allocate_lists=allocate_lists, dorm_types=dorm_types)


# 分配宿舍的页面，选择用户和宿舍
@bp.route('/allocate', methods=['GET', 'POST'])
@admin_required
def allocate_dorm():
    if request.method == 'POST':
        user_id = request.form.get('user_id')  # 获取选择的用户ID
        dorm_id = request.form.get('dorm_id')  # 获取选择的宿舍ID
        check_in_time = request.form.get('check_in_time')  # 获取入住时间

        user = User.query.get(user_id)
        dorm = Dorm.query.get(dorm_id)

        if not user or not dorm:
            flash('无效的用户或宿舍', 'danger')
            return redirect(url_for('main.allocate_dorm'))  # 返回分配页面

        # 将字符串转换为 datetime 类型
        from datetime import datetime

        check_in_time = datetime.strptime(check_in_time, '%Y-%m-%dT%H:%M') if check_in_time else None

        # 检查用户是否已经分配了宿舍
        existing_allocation = Allocation.query.filter_by(user_id=user.id).first()
        if existing_allocation:
            flash(f'{user.username} 已经分配了宿舍，无法再次分配宿舍。', 'danger')
            return redirect(url_for('main.allocate_dorm'))  # 返回分配页面

        if dorm.occupied >= dorm.bed_count:
            flash('该宿舍已满，无法分配', 'danger')
            return redirect(url_for('main.allocate_dorm'))  # 返回分配页面

        # 创建新的分配记录
        allocation = Allocation(user_id=user.id, dorm_id=dorm.id, check_in_time=check_in_time)
        try:
            db.session.add(allocation)
            dorm.occupied += 1  # 更新宿舍已住人数
            db.session.commit()
            flash(f'{user.username} 成功分配到 {dorm.name} 宿舍', 'success')
            return redirect(url_for('main.allocate_dorm'))  # 成功后返回分配页面
        except Exception as e:
            db.session.rollback()
            flash(f'宿舍分配失败: {str(e)}', 'danger')
            return redirect(url_for('main.allocate_dorm'))

    # GET 请求时，显示所有用户和宿舍
    users = User.query.all()
    dorms = Dorm.query.all()
    return render_template('admin/allocate_dorm.html', users=users, dorms=dorms)


# 退宿功能
@bp.route('/allocate_out/<int:user_id>', methods=['GET', 'POST'])
@admin_required
def allocate_out(user_id):
    # 获取该用户的宿舍分配记录
    allocation = Allocation.query.filter_by(user_id=user_id).first()

    if not allocation:
        flash('该用户没有宿舍分配记录', 'danger')
        return redirect(url_for('main.allocate_list'))  # 跳转回宿舍分配列表

    dorm = Dorm.query.get(allocation.dorm_id)

    # 确保对象被绑定到会话中
    try:
        db.session.merge(allocation)  # 显式地将对象加入会话
        db.session.delete(allocation)  # 删除分配记录
        dorm.occupied -= 1  # 更新宿舍已住人数
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        flash(f'退宿失败: {str(e)}', 'danger')

    return redirect(url_for('main.allocate_list'))  # 成功后跳转回宿舍分配列表


# 启用动态搜索
@bp.route('/search_users', methods=['GET'])
@admin_required
def search_users():
    query = request.args.get('q', '').strip()  # 获取并去除首尾空白字符

    # 如果查询为空，返回空列表或所有用户（根据需求）
    if not query:
        return jsonify([])  # 或者 return jsonify([{'id': user.id, 'text': user.username} for user in User.query.all()])

    users = User.query.filter(User.username.like(f'%{query}%')).all()

    # 如果没有匹配的用户
    if not users:
        return jsonify([])

    # 返回查询结果
    return jsonify([{'id': user.id, 'text': user.username} for user in users])


# 更换宿舍
@bp.route('/change_dorm', methods=['GET', 'POST'])
@admin_required
def change_dorm():
    if request.method == 'POST':

        # 处理更换宿舍的逻辑
        user_id = request.form.get('user_id_to_change')  # 获取选择的用户ID
        new_dorm_id = request.form.get('new_dorm_id')  # 获取选择的新宿舍ID

        # 获取用户和新宿舍对象
        user = User.query.get(user_id)
        new_dorm = Dorm.query.get(new_dorm_id)

        # 验证用户和宿舍是否有效
        if not user or not new_dorm:
            flash('无效的用户或宿舍', 'danger')
            return redirect(url_for('main.change_dorm'))  # 返回宿舍更换页面

        # 查找该用户的当前宿舍分配记录
        existing_allocation = Allocation.query.filter_by(user_id=user.id).first()
        if not existing_allocation:
            flash(f'{user.username} 尚未分配宿舍，无法更换宿舍', 'danger')
            return redirect(url_for('main.change_dorm'))  # 返回宿舍更换页面

        # 检查新宿舍是否已满
        if new_dorm.occupied >= new_dorm.bed_count:
            flash('该宿舍已满，无法分配', 'danger')
            return redirect(url_for('main.change_dorm'))  # 返回宿舍更换页面

        # 获取当前宿舍
        current_dorm = Dorm.query.get(existing_allocation.dorm_id)

        # 更新现有的宿舍分配记录
        existing_allocation.dorm_id = new_dorm.id  # 修改为新宿舍ID
        existing_allocation.change_time = datetime.utcnow()  # 更新更换时间

        # 更新宿舍的已住人数
        current_dorm.occupied -= 1  # 减少当前宿舍已住人数
        new_dorm.occupied += 1  # 增加新宿舍的已住人数

        try:
            # 提交更改到数据库
            db.session.commit()
            flash(f'{user.username} 成功更换到 {new_dorm.name} 宿舍', 'success')
            return redirect(url_for('main.change_dorm'))  # 成功后返回宿舍更换页面
        except Exception as e:
            db.session.rollback()
            flash(f'更换宿舍失败: {str(e)}', 'danger')
            return redirect(url_for('main.change_dorm'))

    # GET 请求时返回宿舍更换页面
    users = User.query.all()
    dorms = Dorm.query.all()
    return render_template('admin/dorm_change.html', users=users, dorms=dorms)


# 查询水电费用
@bp.route('/query_utility_fee', methods=['GET', 'POST'])
@admin_required
def query_utility_fee():

    dorm_id = request.args.get('dorm_id', type=int)  # 获取宿舍ID
    month = request.args.get('month')  # 获取月份字符串

    # 获取当前月份
    current_month = datetime.now().month
    current_year = datetime.now().year
    selected_date = datetime(current_year, current_month, 1)  # 当前月份的第一天

    if month:
        try:
            selected_date = datetime.strptime(month, '%Y-%m')
        except ValueError:
            return render_template('admin/meter_list.html', utility_fees=[], dorm_dict={},
                                   selected_month=month, message="无效的月份格式")

    # 查询水电费用记录
    query = db.session.query(UtilityFee).filter(UtilityFee.month == selected_date)

    if dorm_id:
        query = query.filter(UtilityFee.dorm_id == dorm_id)

    try:
        utility_fees = query.all()
    except Exception as e:
        # 记录日志并返回错误信息
        bp.logger.error(f"查询水电费用时出错: {str(e)}")
        return render_template('admin/meter_list.html', utility_fees=[], dorm_dict={},
                               selected_month=selected_date.strftime('%Y-%m'), message="查询出错，请稍后重试")

    # 如果没有找到数据，返回一个友好的提示
    if not utility_fees:
        return render_template('admin/meter_list.html', utility_fees=[], dorm_dict={},
                               selected_month=selected_date.strftime('%Y-%m'), message="没有数据")
    # 查询所有宿舍
    dorm_ids = {fee.dorm_id for fee in utility_fees}
    dorms = Dorm.query.filter(Dorm.id.in_(dorm_ids)).all()
    dorm_dict = {dorm.id: dorm.name for dorm in dorms}

    return render_template('admin/meter_list.html', utility_fees=utility_fees, dorm_dict=dorm_dict,
                           selected_month=selected_date.strftime('%Y-%m'))


# 计算水电费用
@bp.route('/calculate_utility_fee', methods=['GET', 'POST'])
@admin_required
def calculate_utility_fee():
    if request.method == 'POST':
        dorm_id = request.form.get('dorm_id', type=int)  # 获取宿舍ID
        month = request.form.get('month')  # 获取月份字符串

        # 获取当前月份
        current_month = datetime.now().month
        current_year = datetime.now().year
        selected_date = datetime(current_year, current_month, 1)  # 当前月份的第一天

        # 如果传入了月份参数，解析该月份
        if month:
            selected_date = datetime.strptime(month, '%Y-%m')

        # 查询当前月份的所有 Meter 记录
        query = db.session.query(Meter).filter(Meter.month == selected_date)

        if dorm_id:
            query = query.filter(Meter.dorm_id == dorm_id)  # 如果指定了宿舍ID，进行过滤

        # 获取结果集
        meters = query.all()

        # 计算每个宿舍的水电费用
        utility_fees = []
        dorm_ids = set()  # 用于记录不同的宿舍ID

        for meter in meters:
            dorm_ids.add(meter.dorm_id)

            # 获取该宿舍上个月的水电记录
            last_meter = Meter.query.filter(Meter.dorm_id == meter.dorm_id, Meter.month < meter.month).order_by(
                Meter.month.desc()).first()

            if last_meter:
                # 本月读数 - 上月读数 = 用量
                water_usage = meter.water_reading - last_meter.water_reading
                electricity_usage = meter.electricity_reading - last_meter.electricity_reading
            else:
                # 如果没有上月记录，初始读数为0
                water_usage = meter.water_reading
                electricity_usage = meter.electricity_reading

            # 假设水费和电费的单价
            water_rate = 2.5  # 水费单价
            electricity_rate = 0.6  # 电费单价

            # 计算费用
            water_fee = water_usage * water_rate
            electricity_fee = electricity_usage * electricity_rate
            total_fee = water_fee + electricity_fee

            # 如果该宿舍和月份的费用已存在，则更新
            existing_fee = UtilityFee.query.filter_by(dorm_id=meter.dorm_id, month=meter.month).first()
            if existing_fee:
                existing_fee.water_fee = water_fee
                existing_fee.electricity_fee = electricity_fee
                existing_fee.total_fee = total_fee
                utility_fees.append(existing_fee)  # 更新已有记录时，也添加到返回结果中
            else:
                # 否则插入新记录
                utility_fee = UtilityFee(
                    dorm_id=meter.dorm_id,
                    month=meter.month,
                    water_fee=water_fee,
                    electricity_fee=electricity_fee,
                    total_fee=total_fee
                )
                db.session.add(utility_fee)
                utility_fees.append(utility_fee)  # 新增记录时添加到返回结果中

        # 提交到数据库
        db.session.commit()

        # 获取宿舍信息
        dorms = Dorm.query.all()
        dorm_dict = {dorm.id: dorm.name for dorm in dorms}  # 更新宿舍信息字典

        return render_template('admin/meter_js.html', utility_fees=utility_fees,
                               selected_month=selected_date.strftime('%Y-%m'), dorm_dict=dorm_dict)

    # 显示计算界面的表单

    dorms = Dorm.query.all()
    dorm_dict = {dorm.id: dorm.name for dorm in dorms}  # 创建一个字典，宿舍ID -> 宿舍名
    return render_template('admin/meter_js.html', dorms=dorms, dorm_dict=dorm_dict)


# 添加水电读数（支持单个或批量添加）
@bp.route('/add_meter_reading', methods=['GET', 'POST'])
@admin_required
def add_meter_reading():
    if request.method == 'POST':
        dorm_id = request.form.get('dorm_id', type=int)
        month = datetime.strptime(request.form.get('month'), '%Y-%m')
        water_reading = request.form.get('water_reading', type=float)
        electricity_reading = request.form.get('electricity_reading', type=float)

        meter = Meter(
            dorm_id=dorm_id,
            month=month,
            water_reading=water_reading,
            electricity_reading=electricity_reading
        )

        db.session.add(meter)
        db.session.commit()
        flash('水电读数添加成功！')
        return redirect(url_for('main.add_meter_reading'))

    # 获取当前日期和上个月日期
    current_date = datetime.now()
    # 当前月份的第一天和下个月的第一天

    current_month_start = current_date.replace(day=1)
    next_month_start = (current_date.replace(day=1) + timedelta(days=32)).replace(day=1)

    # 上个月的第一天
    last_month_start = (current_date.replace(day=1) - timedelta(days=1)).replace(day=1)

    # 查询当前月的水电读数（当前月的第一天到下个月的第一天）
    # 查询当前月的水电读数
    current_month_readings = Meter.query.filter(
        extract('year', Meter.month) == current_date.year,
        extract('month', Meter.month) == current_date.month
    ).all()

    # 查询上月的水电读数（上个月的第一天到当前月的第一天）
    last_month_readings = Meter.query.filter(
        extract('year', Meter.month) == last_month_start.year,
        extract('month', Meter.month) == last_month_start.month
    ).all()

    # 将数据按宿舍ID整理为字典，便于在模板中按宿舍ID查找
    current_month_readings_dict = {reading.dorm_id: reading for reading in current_month_readings}
    last_month_readings_dict = {reading.dorm_id: reading for reading in last_month_readings}

    # 渲染模板并传递数据
    return render_template('admin/meter_add.html',
                           dorms=Dorm.query.all(),
                           current_month_readings=current_month_readings_dict,
                           last_month_readings=last_month_readings_dict,
                           current_month=current_date.month,
                           last_month=last_month_start.month)
